C++

您所在的位置:网站首页 share_ptr weak_ptr C++

C++

2023-10-19 06:14| 来源: 网络整理| 查看: 265

智能指针:

是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针;

行为类似于常规指针,更容易也更安全的使用动态内存,负责自动释放所指向的对象;

智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放;

三种智能指针:shared_ptr、unique_ptr、weak_ptr,均定义在memory头文件中。

1、shared_ptr 定义:

shared_ptr允许多个对象指向同一个对象,是一个标准的共享所有权的智能指针,C++11引入到C++ STL

用法: shared_ptr p1; //一个指向string类型的shared_ptr指针p1 shared_ptr p2;// 一个指向int型list的shared_ptr指针p2

默认初始化的只能指针中保存着一个空指针,解引用一个智能指针返回它所指向的对象

操作: make_shared (args) 返回一个shared_ptr,指向一个动态分配的类型为T的对象,用args初始化此对象 shared_ptr p(q) p是shared_ptr q的拷贝;该操作会递增q中的计数器,q中的指针必须能转化为T* p=q p和q都是shared_ptr,所保存的指针能够相互转化;该操作递增q的引用计数,递减P的引用计数 p.unique() 若p.use_count()为1,返回true,否则返回false p.use_count() 返回和p共享对象的智能指针数量(主要用于调试) p.get() 返回p中保存的指针(返回一个内置指针,指向智能指针管理的对象 int *q=p.get()) swap(p,q)/p.swap(q) 交换p,q中的指针 p 用作一个条件判断,若指向一个对象,最为true *p 解引用,获得它所指对象 p->mem 等价于(*p).mem,获取所指对象成员 make_shared函数:

在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr,使用该函数时,必须指定想要创建的对象类型

shared_ptr p3=make_shared(42) 指向一个值为42的int shared_ptr p4=make_shared(5,'b') 指向一个值为'bbbbb'的string的shared_ptr shared_ptr p5=make_shared() 指向一个值初始化的int,值为0

通常用auto定义一个对象来保存make_shared的结果

//p6指向一个动态分配的空vector auto p6=make_shared(); 拷贝与赋值:

进行拷贝与赋值时,每个shared_ptr都会记录有多少的其他shared_ptr指向相同对象;

每一个shared_ptr都有一个关联计数器,叫做引用计数,拷贝时,计数器递增;

一个shared_ptr被赋予新值(改变指向对象,即不指向当前对象时)或被销毁时,计数器递减,减为0时自动释放所管理的对象。

auto r=make_shared(42); r=q;//给r赋值,令它指向q所指的地址 //递增q指向对象的引用计数 //递减r原来所指对象(42)的引用计数 //r原来指向的对象没有引用者会自动释放

shared_ptr的析构函数会递减他所指对象的引用计数,变为0时会销毁对象,释放它所占的内存

ps:使用动态内存的原因

     1、程序不知道自己需要使用多少对象

     2、程序不知道所需对象的准确类型

     3、程序需要在多个对象间共享数据

2、unique_str 定义:

C++11引入,替代不安全的auto_ptr,一个unique_str"拥有"它所指的对象,持有对对象的独有权。

特点:

两个unique_ptr 不能指向一个对象,即 unique_ptr 不共享它所管理的对象;

只能移动unique_ptr,即对资源管理权限可以实现转移,意味着内存资源所有权可以转移到另一个 unique_ptr,并且原始    unique_ptr 不再拥有此资源;

运行效率高,因为通过 unique_ptr 的移动构造函数,不再需要进行复制操作;

与所指对象的关系:

在智能指针生命周期内,可以改变智能指针所指对象,如创建智能指针时通过构造函数指定、通过 reset 方法重新指定、通过 release 方法释放所有权、通过移动语义转移所有权,unique_ptr 还可能没有对象,这种情况被称为 empty。

操作: //智能指针的创建 unique_ptr u_i; //创建空智能指针 u_i.reset(new int(3)); //绑定动态对象 unique_ptr u_i2(new int(4));//创建时指定动态对象 unique_ptr u(d); //创建空 unique_ptr,执行类型为 T 的对象,用类型为 D 的对象 d 来替代默认的删除器 delete //所有权的变化 unique_ptr u_s(new string("abc")); unique_ptr u_s2 = std::move(u_s); //所有权转移(通过移动语义),u_s所有权转移后,变成“空指针” u_s2.reset(u_s.release()); //所有权转移 u_s2=nullptr;//显式销毁所指对象,同时智能指针变为空指针。与u_s2.reset()等价 u.release(); //放弃控制权,返回指针,u置空 int *p_i = u_i2.release(); u.reset(); //释放u所指对象 u.reset(q) //如果提供内置指针q,u指向q,否则置空 u.reser(nullptr) 3、weak_ptr 定义:

一种不控制所指对象生命周期的智能指针,它指向由一个shared_ptr管理的对象。

weak_ptr 是为了配合 shared_ptr 而引入的一种智能指针,它更像是 shared_ptr 的一个助手而不是智能指针,因为它不具有普通指针的行为,没有重载 operator* 和 operator-> ,因此取名为 weak,表明其是功能较弱的智能指针。

weak_ptr 只对 shared_ptr 进行引用,而不改变其引用计数,当被观察的 shared_ptr 失效后,相应的 weak_ptr 也相应失效。

操作: weak_ptr w; //创建空 weak_ptr,可以指向类型为 T 的对象 weak_ptr w(sp); //与 shared_ptr 指向相同的对象,shared_ptr 引用计数不变。T必须能转换为 sp 指向的类型 w=p; //p 可以是 shared_ptr 或 weak_ptr,赋值后 w 与 p 共享对象 w.reset(); //将 w 置空 w.use_count(); //返回与 w 共享对象的 shared_ptr 的数量 w.expired(); //若 w.use_count() 为 0,返回 true,否则返回 false w.lock(); //如果 expired() 为 true,返回一个空 shared_ptr,否则返回非空 shared_ptr

使用 weak_ptr 的成员函数 use_count() 可以观测资源的引用计数,另一个成员函数 expired() 的功能等价于 use_count()==0,但更快,表示被观测的资源(也就是 shared_ptr 管理的资源)已经不复存在。weak_ptr 可以使用一个非常重要的成员函数lock()从被观测的 shared_ptr 获得一个可用的 shared_ptr 管理的对象, 从而操作资源。但当 expired()==true 的时候,lock() 函数将返回一个存储空指针的 shared_ptr。

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3